#ifndef SLICEITERATOR_HPP
#define SLICEITERATOR_HPP

#include <Eigen/Core>
#include <QListIterator>
#include <iostream>

#include "slice.hpp"

using namespace Eigen;

class SliceIterator {
  public:
    SliceIterator(Slice &slice);
    SliceIterator(Slice &first,Slice &second);
    SliceIterator(Slice &first,Slice &second,Slice &third);

    void execute(void (* callback) (unsigned char & value));
    void execute(void (* callback) (unsigned char & value,const Vector3i &index));
    void execute(void (* callback) (unsigned char & value,void *param),void *param);
    void execute(void (* callback) (unsigned char & value,const Vector3i &index,void *param),
        void *param);
    void execute(void (*callback) (Slice &slice,void *param),void *param);

    void execute(void (* callback) (unsigned char & first,unsigned char & second));
    void execute(void (* callback) (unsigned char & first,unsigned char & second,
          const Vector3i &index));
    void execute(void (* callback) (unsigned char & first,unsigned char & second,
          void *param),void *param);
    void execute(void (* callback) (unsigned char & first,unsigned char & second,
          const Vector3i &index,void *param),void *param);
    void execute(void (*callback) (Slice &first,Slice &second,void *param),void *param);

    void execute(void (* callback) (unsigned char &first,unsigned char &second,
          unsigned char & third));
    void execute(void (* callback) (unsigned char &first,unsigned char &second,
          unsigned char & third,const Vector3i &index));
    void execute(void (* callback) (unsigned char &first,unsigned char &second,
          unsigned char & third,void *param),void *param);
    void execute(void (* callback) (unsigned char &first,unsigned char &second,
          unsigned char & third,const Vector3i &index,void *param),void *param);
    void execute(void (*callback) (Slice &first,Slice &second,Slice &third));
    void execute(void (*callback) (Slice &first,Slice &second,Slice &third,void *param),void *param);

    //template <typename T>
    //void execute(void (* callback) (unsigned char & value,T &param),T &param);

    const Vector3i & getIndex() const;
    const int & x() const;
    const int & y() const;
    const int & z() const;
    void next();
    unsigned char value() const;
    unsigned char firstValue() const;
    unsigned char secondValue() const;
    unsigned char thirdValue() const;
    bool hasNext() const;
    void toFront();

    void setIndices(const QList<Vector3i> &indices,const Vector3i &offset=Vector3i(0,0,0));
    void clearIndices();
  private:
    Slice *first,*second,*third;
    bool atBack,atFront;
    QList<Vector3i> indices;
    int indexCounter;
};

#endif
